﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using NETMF.OpenSource.XBee;
using NETMF.OpenSource.XBee.Api;
using NETMF.OpenSource.XBee.Api.Common;
using WpfApplication1.Annotations;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window 
    {
        private XBeeApi _api;

        private List<NodeInfo> _nodes;
        private List<NodeInfo> Nodes
        {
            get
            {
                if (_nodes == null)
                {
                    _nodes = new List<NodeInfo>();
                }

                return _nodes;
            }

            set
            {
                if (_nodes == null)
                {
                    _nodes = new List<NodeInfo>();
                }
            }
        }

        private object _nodeListLock = new object();
        public ObservableCollection<NodeInfo> NodeList { get; set; }

        private object _logDataLock = new object();
        public ObservableCollection<string> LogData { get; set; }

        public MainWindow()
        {
            InitializeComponent();

            //_logData = new ObservableCollection<string>();
            _api = new XBeeApi("COM7", 9600);


            LogData = new ObservableCollection<string>();
            BindingOperations.EnableCollectionSynchronization(LogData, _logDataLock);

            NodeList = new ObservableCollection<NodeInfo>();
            BindingOperations.EnableCollectionSynchronization(NodeList, _nodeListLock);

            this.DataContext = this;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //lstHistory.Items.Add("starting up");
            LogData.Insert(0, "starting up");

            _api.DataReceived += OnDataReceived;

            _api.EnableDataReceivedEvent();
            _api.EnableAddressLookup();
            _api.EnableModemStatusEvent();

            _api.AddPacketListener(new PacketListener());
            _api.AddPacketListener(new IoSampleListener(LogData));

            if (!_api.IsConnected())
            {
                _api.Open();
            }

            //QueryBaseStation(null, null);

            LogData.Insert(0, "Discover Nodes");
            _api.DiscoverNodes(OnNodeDiscovered);
        }

        private void OnDataReceived(XBeeApi receiver, byte[] data, XBeeAddress sender)
        {
            throw new NotImplementedException();
        }

        private void OnNodeDiscovered(DiscoverResult node)
        {
            Nodes.Add(node.NodeInfo);
            LogData.Insert(0, "Node: " + node.NodeInfo);
            NodeList.Add(node.NodeInfo);
        }

        private void QueryBaseStation(object sender, RoutedEventArgs e)
        {
            lstBaseStationDetails.Items.Add("Addressing Commands");
            AtResponse dh = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DestinationAddressHigh).GetResponse();
            lstBaseStationDetails.Items.Add("dh: " + ByteArrayToString(dh.Value));

            AtResponse dl = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DestinationAddressLow).GetResponse();
            lstBaseStationDetails.Items.Add("dl: " + ByteArrayToString(dl.Value));

            AtResponse my = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.NetworkAddress).GetResponse();
            lstBaseStationDetails.Items.Add("my: " + ByteArrayToString(my.Value));

            AtResponse mp = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.ParentAddress).GetResponse();
            lstBaseStationDetails.Items.Add("mp: " + ByteArrayToString(mp.Value));

            AtResponse nc = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.NumberOfRemainingChildren).GetResponse();
            lstBaseStationDetails.Items.Add("nc: " + ByteArrayToString(nc.Value));

            AtResponse sh = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.SerialNumberHigh).GetResponse();
            lstBaseStationDetails.Items.Add("sh: " + ByteArrayToString(sh.Value));

            AtResponse sl = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.SerialNumberLow).GetResponse();
            lstBaseStationDetails.Items.Add("sl: " + ByteArrayToString(sl.Value));

            AtResponse ni = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.NodeIdentifier).GetResponse();
            lstBaseStationDetails.Items.Add("ni: " + ByteArrayToString(ni.Value));

            AtResponse se = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.SourceEndpoint).GetResponse();
            lstBaseStationDetails.Items.Add("se: " + ByteArrayToString(se.Value));

            AtResponse de = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DestinationEndpoint).GetResponse();
            lstBaseStationDetails.Items.Add("de: " + ByteArrayToString(de.Value));

            AtResponse ci = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.ClusterIdentifier).GetResponse();
            lstBaseStationDetails.Items.Add("ci: " + ByteArrayToString(ci.Value));

            AtResponse np = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.MaxRFPayloadBytes).GetResponse();
            lstBaseStationDetails.Items.Add("np: " + ByteArrayToString(np.Value));

            AtResponse dd = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DeviceTypeIdentifier).GetResponse();
            lstBaseStationDetails.Items.Add("dd: " + ByteArrayToString(dd.Value));


            lstBaseStationDetails.Items.Add("Networking Commands");

            AtResponse ch = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.OperatingChannel).GetResponse();
            lstBaseStationDetails.Items.Add("ch: " + ByteArrayToString(ch.Value));

            AtResponse da = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.ForceDisassociation).GetResponse();
            lstBaseStationDetails.Items.Add("da: " + ByteArrayToString(da.Value));

            AtResponse id = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.ExtendedPanId).GetResponse();
            lstBaseStationDetails.Items.Add("id: " + ByteArrayToString(id.Value));

            AtResponse op = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.OperatingPanId).GetResponse();
            lstBaseStationDetails.Items.Add("op: " + ByteArrayToString(op.Value));

            AtResponse nh = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.MaximumUnicastHops).GetResponse();
            lstBaseStationDetails.Items.Add("nh: " + ByteArrayToString(nh.Value));

            AtResponse bh = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.BroadcastHops).GetResponse();
            lstBaseStationDetails.Items.Add("bh: " + ByteArrayToString(bh.Value));

            AtResponse oi = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.OperatingPanId).GetResponse();
            lstBaseStationDetails.Items.Add("oi: " + ByteArrayToString(oi.Value));

            AtResponse nt = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.NodeDiscoverTimeout).GetResponse();
            lstBaseStationDetails.Items.Add("nt: " + ByteArrayToString(nt.Value));

            AtResponse no = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.NetworkDiscoveryOptions).GetResponse();
            lstBaseStationDetails.Items.Add("no: " + ByteArrayToString(no.Value));

            AtResponse sc = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.ScanChannels).GetResponse();
            lstBaseStationDetails.Items.Add("sc: " + ByteArrayToString(sc.Value));

            AtResponse sd = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.ScanChannels).GetResponse();
            lstBaseStationDetails.Items.Add("sd: " + ByteArrayToString(sd.Value));

            AtResponse zs = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.ZigBeeStackProfile).GetResponse();
            lstBaseStationDetails.Items.Add("zs: " + ByteArrayToString(zs.Value));

            AtResponse nj = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.NodeJoinTime).GetResponse();
            lstBaseStationDetails.Items.Add("nj: " + ByteArrayToString(nj.Value));

            AtResponse jv = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.ChannelVerification).GetResponse();
            lstBaseStationDetails.Items.Add("jv: " + ByteArrayToString(jv.Value));

            AtResponse nw = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.NetworkWatchdogTimeout).GetResponse();
            lstBaseStationDetails.Items.Add("nw: " + ByteArrayToString(nw.Value));

            AtResponse jn = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.JoinNotification).GetResponse();
            lstBaseStationDetails.Items.Add("jn: " + ByteArrayToString(jn.Value));

            AtResponse ar = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.AggregateRoutingNotification).GetResponse();
            lstBaseStationDetails.Items.Add("ar: " + ByteArrayToString(ar.Value));

            AtResponse dj = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DisableJoining).GetResponse();
            lstBaseStationDetails.Items.Add("dj: " + ByteArrayToString(dj.Value));

            AtResponse ii = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.InitialId).GetResponse();
            lstBaseStationDetails.Items.Add("ii: " + ByteArrayToString(ii.Value));





            AtResponse apienable = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.ApiEnable).GetResponse();
            lstBaseStationDetails.Items.Add("api enable: " + ByteArrayToString(apienable.Value));

            AtResponse firmware = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.FirmwareVersion).GetResponse();
            lstBaseStationDetails.Items.Add("firmware: " + ByteArrayToString(firmware.Value));

            AtResponse hardware = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.HardwareVersion).GetResponse();
            lstBaseStationDetails.Items.Add("hardware: " + ByteArrayToString(hardware.Value));
        }

        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            /*
            var dio1 = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DIO1Config, new byte[]{2}).To(Nodes[0]).GetResponse();
            var dio1c = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DIO1Config).To(Nodes[0]).GetResponse();

            var dio2 = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DIO2Config, new byte[]{2}).To(Nodes[0]).GetResponse();
            var dio2c = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DIO2Config).To(Nodes[0]).GetResponse();

            var dio11 = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DIO11Config, new byte[] {0}).To(Nodes[0]).GetResponse();
            var dio11c = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DIO11Config).To(Nodes[0]).GetResponse();

            var dh = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DestinationAddressHigh, new byte[]{0}).To(Nodes[0]).GetResponse();
            //var dh = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DestinationAddressHigh, _addresshigh).To(Nodes[0]).GetResponse();
            var dhc = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DestinationAddressHigh).To(Nodes[0]).GetResponse();

            var dl = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DestinationAddressLow, new byte[]{0}).To(Nodes[0]).GetResponse();
            //var dl = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DestinationAddressLow, _addresslow).To(Nodes[0]).GetResponse();
            var dlc = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.DestinationAddressLow).To(Nodes[0]).GetResponse();
            */

            var sp = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.SleepPeriod, new byte[] { 0x0a, 0xf0 }).To(Nodes[0]).GetResponse();

            var samplerate = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.SampleRate, new byte[] { 0x00 }).To(Nodes[0]).GetResponse();
            var sampleratec = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.SampleRate).To(Nodes[0]).GetResponse();


        }

        public static string ByteArrayToString(byte[] ba)
        {
            string hex = BitConverter.ToString(ba);
            return hex.Replace("-", "");
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            LogData.Insert(0, "Discover Nodes");
            _api.DiscoverNodes(OnNodeDiscovered);
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            try
            {
                var sm = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.SleepMode).To(Nodes[0]).GetResponse();
                var sp = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.SleepPeriod).To(Nodes[0]).GetResponse();
                var st = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.TimeBeforeSleep).To(Nodes[0]).GetResponse();
                var sn = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.NumberOfSleepPeriods).To(Nodes[0]).GetResponse();
                var wh = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.WakeHost).To(Nodes[0]).GetResponse();
                var so = _api.Send(NETMF.OpenSource.XBee.Api.Zigbee.AtCmd.SleepOptions).To(Nodes[0]).GetResponse();
            }
            catch (Exception)
            {
                
            }
        }
    }
}
